package com.github.common.extend.demo.config.filetask.config;

import com.github.common.extend.demo.config.filetask.*;
import com.github.common.extend.demo.config.filetask.download.FileTaskDownloader;
import com.github.common.extend.demo.config.filetask.download.FileTaskDownloaderImpl;
import com.github.common.extend.demo.config.filetask.excel.ExcelTaskDownloaderImpl;
import com.github.common.extend.demo.util.concurrent.ProxyExecutorService;
import com.github.common.extend.demo.util.concurrent.TaskInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wangjj7
 * @date 2023/8/18
 * @description
 */
@Slf4j
//@Configuration //需要先实现TaskStorage和XFileStorage
public class FileTaskConfiguration implements InitializingBean {

    private ExecutorService executorService;

    public ExecutorService executorService(){
        return executorService;
    }

    public String idGenerate(){
        return UUID.randomUUID().toString();
    }

    @Bean
    @ConfigurationProperties(prefix = "download.task")
    public FileTaskProperties xFileTaskProperties(){
        return new FileTaskProperties();
    }

    @Bean
    public TaskStorage xTaskStorage(){
        //TODO
        throw new IllegalStateException();
    }

    @Bean
    public FileStorage xFileStorage(){
        //TODO
        throw new IllegalStateException();
    }

    @Bean
    public FileTaskManagerImpl xFileTaskManagerImpl(FileTaskProperties properties ,
                                                    TaskStorage TaskStorage, FileStorage fileStorage,
                                                    @Autowired(required = false) List<FileTaskManagerInterceptor> interceptors)
    {
        return new FileTaskManagerImpl(this::idGenerate ,properties , TaskStorage,
                fileStorage ,interceptors ,executorService());
    }

    @Bean
    public FileTaskDownloaderImpl xFileTaskDownloaderImpl(FileTaskManager fileTaskManager){
        return new FileTaskDownloaderImpl(this::idGenerate ,fileTaskManager);
    }

    @Override
    public void afterPropertiesSet() {
        initAsyncTaskExecutor();
    }

    @Bean
    public ExcelTaskDownloaderImpl xExcelTaskDownloaderImpl(FileTaskDownloader fileTaskDownloader)
    {
        return new ExcelTaskDownloaderImpl(fileTaskDownloader ,this::idGenerate, executorService());
    }

    private void initAsyncTaskExecutor()
    {
        if (executorService == null){
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                    5, 10, 60, TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(100),
                    new ThreadFactory() {
                        private final AtomicInteger inc = new AtomicInteger();

                        @Override
                        public Thread newThread(Runnable r) {
                            Thread thread = new Thread(r, "downloadTaskExecutor-" + inc.getAndIncrement());
                            thread.setDaemon(true);
                            return thread;
                        }
                    } ,(r, executor) -> {
                        log.error("文件任务超负荷，新任务不再尝试异常执行");
                    });
            executorService = new ProxyExecutorService(threadPoolExecutor ,() -> new TaskInterceptor() {
                @Override
                public void postInit() {
                    //TODO
                }

                @Override
                public void preExe() {
                    //TODO
                }

                @Override
                public void postExe() {
                    //TODO
                }
            });
        }
    }

}
